﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_THREAD_INTERFACE_H
#define _UXS_THREAD_INTERFACE_H

#pragma once

#include "IThreadOp.h"

namespace UX_STL
{
namespace UXTypesExt
{

	//
	// Thread Type
	//

	namespace e_thread
	{
		enum	type :	uint16
		{
			UNKNOWN			= 0,
			_RENDER_CONTEXT	= 0x0100,
			_WINDOW			= 0x0200,

			THREAD_0		= 0x0001,	// default thread type

			MAIN_WINDOW		= _RENDER_CONTEXT | _WINDOW | 0x0010,	// window proc thread
			RENDER_WINDOW	= _RENDER_CONTEXT | _WINDOW | 0x0020,	// additional window this shared render context
			LOAD_CONTEXT	= _RENDER_CONTEXT | _WINDOW | 0x0040,	// load thread with render context
			
			// for queries only
			ALL				= 0xFFFF,
		};
	};


	
	//
	// Thread Interface
	//

	class UX_EXPORT IThread
	{
		friend class CThreadManager;

	public:
		typedef queue< IThreadOp *, TFastCopyStrategy< IThreadOp *> >		threadop_queue_t;
		
	protected:
		uint			_uThreadID;
		atomic_usize	_uEmploymentRate;
		e_thread::type	_eThreadType;

	public:
		IThread(e_thread::type eType): _eThreadType(eType), _uEmploymentRate(-1), _uThreadID(0) {}
		virtual ~IThread() {}

		virtual bool Push(IThreadOp *pOp, bool bHighPriority = false) = 0;
		virtual void Exit() = 0;
		virtual bool Pause() = 0;
		virtual bool Resume() = 0;
		virtual bool IsCurrent() = 0;

		void SetThreadType(e_thread::type eType)	{ _eThreadType = eType; }

		e_thread::type	ThreadType()		const	{ return _eThreadType; }
		usize			EmploymentRate()	const	{ return _uEmploymentRate; }
		uint			ThreadID()			const	{ return _uThreadID; }
	};



	//
	// Thread
	//

	class UX_EXPORT CThread : public IThread
	{
	protected:
		Thread				_sThread;
		threadop_queue_t	_aOpQueue;
		Mutex	_sCSLockQueue;
		volatile bool		_bLooping : 1;

	protected:
		int _Loop();

	public:
		CThread();
		~CThread();
		
		bool Run (/*e_thread_priority::type ePriority*/);

		// IThread //
		virtual bool Push(IThreadOp *pOp, bool bHighPriority = false);
		virtual void Exit();
		virtual bool Pause();
		virtual bool Resume();
		virtual bool IsCurrent();
	};



	//
	// Window Thread
	//

	class UX_EXPORT CWindowThread : public IThread, public IWindowUpdater
	{
	protected:
		Ptr< CWindow >		_pWindow;
		Thread				_sThread;
		threadop_queue_t	_aOpQueue;
		Mutex	_sCSLockQueue;

	public:
		CWindowThread(CWindow *pWnd);
		~CWindowThread();

		Thread *	GetThread()		{ return &_sThread; }

		// IThread //
		virtual bool Push(IThreadOp *pOp, bool bHighPriority = false);
		virtual void Exit();
		virtual bool Pause();
		virtual bool Resume();
		virtual bool IsCurrent();
		
		// IWindowUpdater //
		virtual void OnUpdate(CWindow *);
	};



	//
	// Window Thread
	//

	class UX_EXPORT CMainWindowThread : public IThread, public IWindowUpdater
	{
	protected:
		Ptr< CWindow >		_pWindow;
		CurrentThread		_sThread;
		threadop_queue_t	_aOpQueue;
		Mutex				_sCSLockQueue;

	public:
		CMainWindowThread(CWindow *pWnd);
		~CMainWindowThread();

		// IThread //
		virtual bool Push(IThreadOp *pOp, bool bHighPriority = false);
		virtual void Exit();
		virtual bool Pause();
		virtual bool Resume();
		virtual bool IsCurrent();
		
		// IWindowUpdater //
		virtual void OnUpdate(CWindow *);
	};

//-------------------------------------------------------------------

}	// UXTypesExt
}	// UX_STL

#endif	// _UXS_THREAD_INTERFACE_H